 /*                                                                      
 Copyright 2020 Sean Xiao, jxzsxsp@qq.com
                                                                         
 Licensed under the Apache License, Version 2.0 (the "License");         
 you may not use this file except in compliance with the License.        
 You may obtain a copy of the License at                                 
                                                                         
     http://www.apache.org/licenses/LICENSE-2.0                          
                                                                         
 Unless required by applicable law or agreed to in writing, software    
 distributed under the License is distributed on an "AS IS" BASIS,       
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and     
 limitations under the License.                                          
 */

// RV32I(整数指令集)：47条指令，32位地址空间与整数指令，支持32个通用整数寄存器
// RV32E(整数指令集)：47条指令，RV32I的子集，仅支持16个通用整数寄存器
// RV32M(乘法除法指令集)：8条指令，整数乘法与除法指令
// RV32F(单精度浮点指令集):26条指令，单精度(32bit)浮点指令
// RV32D(双精度浮点指令集):26条指令，双精度(64bit)浮点指令，必须支持F扩展指令
// RV32A(原子指令集):11条指令，存储原子(Atomic)操作指令和Load-Reserved/Store-Conditional指令
// RV32G(通用指令集)：RV32M、RV32F、RV32D、RV32A
// RV16C(压缩扩展指令集)：46条指令，压缩指令集，指令长度为16位，比标准的RV32I，代码效率可以提高25-30%
// RV32V(向量扩展指令集)

// RV64I(整数指令集)：59条指令，64位地址空间与整数指令及一部分32位的整数指令
// RV128I(整数指令集)：71条指令，128位地址空间与整数指令及一部分64位和32位的指令

// I型指令，immediate立即数指令
// imm[31:20]_rs1[19:15]_funct3[14:12]_rd[11:7]_opcode[6:0]
`define OP_TYPE_I       7'b001_0011         // 立即数操作码opcode
`define FUNCT3_ADDI     3'b000              // 立即数加法指令：add immediate，例：ADDI rd,rs1,0 (MV rd,rs1)
`define FUNCT3_SLTI     3'b010              // 立即数据小于指令：set less than immediate，例：SLTI rd,rs1,1
`define FUNCT3_SLTIU    3'b011              // 无符号立即数小于指令：set less than immediate unsigned，例：SLTIU rd,rs1,1 (SEQZ rd,rs1)
`define FUNCT3_XORI     3'b100              // 立即数异或指令：xor immediate，例：XORI rd,rs1,-1 (NOT rd,rs1)
`define FUNCT3_ORI      3'b110              // 立即数或指令：or immediate，例：ORI rd,rs1,1
`define FUNCT3_ANDI     3'b111              // 立即数与指令：and immediate，例：ANDI rd,rs1,1
`define FUNCT3_SLLI     3'b001              // 立即数逻辑左移：shift left logical immediate，例：SLLI rd,rs1,imm[4:0] (imm[11:5]=7'b000_0000)
// SRLI, SRAI 的funct3编码相同3'b101，由imm[11:5]内容不同区分
// 立即数逻辑右移：shift right logical immediate，例：SRLI rd,rs1,shamt[4:0] (imm[11:5]=7'b000_0000)
// 立即数算术右移：shift right arithmetical immediate，例：SRLI rd,rs1,shamt[4:0] (imm[11:5]=7'b010_0000)
`define FUNCT3_SRI      3'b101              // 立即数算术右移：shift right arithmetical/logical immediate
`define FUNCT7_SRLI     7'b000_0000
`define FUNCT7_SRAI     7'b010_0000

// U型指令，有LUI和AUIPC两条,立即数是20位
// imm[31:12]_rd[11:7]_opcode[6:0]
`define OP_LUI_TYPE_U   7'b011_0111         // 将U_imm写入rd的高20位，rd低12位补零，例：LUI rd,imm[31:12]
`define OP_AUIPC_TYPE_U 7'b001_0111         // 将20位的立即数放置32位的高20位，将低12补零后和当前的PC相加写入rd寄存器，例：AUIPC rd,imm[31:12]

// R和M型指令
// funct7[31:25]_rs2[24:20]_rs1{19:15]_funct3[14:12]_rd[11:7]_opcode[6:0]
`define OP_TYPE_R_M     7'b011_0011         // R和M型指令操作码opcode
// R型指令
`define FUNCT3_ADD_SUB  3'b000              // 加减法指令：add/substract，例：ADD rd,rs1,rs2 | SUB rd,rs1,rs2
`define FUNCT3_SLL      3'b001              // 逻辑左移指令：shift left logical，例：SLL rd,rs1,rs2
`define FUNCT3_SLT      3'b010              // 小有符号于指令：set less than，例：SLT rd,rs1,rs2
`define FUNCT3_SLTU     3'b011              // 无符号小于指令：set less than unsigned，例：SLTU rd,rs1,rs2
`define FUNCT3_XOR      3'b100              // 按位异或指令：xor，例：XOR rd,rs1,rs2
`define FUNCT3_SRL_SRA  3'b101              // 算术/逻辑右移指令：shift right logical/arithmetical，例：SRL rd,rs1,rs2 | SRA rd,rs1,rs2
`define FUNCT3_OR       3'b110              // 按位或指令：or，例：OR rd,rs1,rs2
`define FUNCT3_AND      3'b111              // 按位与指令：and，例：AND rd,rs1,rs2
`define FUNCT7_ADD_SRL  7'b000_0000         // ADD/SLT/SLTU/AND/OR/XOR/SLL/SRL
`define FUNCT7_SUB_SRA  7'b010_0000         // SUB/SRA
// M型指令
`define INST_MUL    3'b000
`define INST_MULH   3'b001
`define INST_MULHSU 3'b010
`define INST_MULHU  3'b011
`define INST_DIV    3'b100
`define INST_DIVU   3'b101
`define INST_REM    3'b110
`define INST_REMU   3'b111

// L type inst
`define INST_TYPE_L 7'b0000011
`define INST_LB     3'b000
`define INST_LH     3'b001
`define INST_LW     3'b010
`define INST_LBU    3'b100
`define INST_LHU    3'b101

// S type inst
`define INST_TYPE_S 7'b0100011
`define INST_SB     3'b000
`define INST_SH     3'b001
`define INST_SW     3'b010

// J型指令
// imm[31:12]_rd[11:7]_opcode[6:0]
// imm[31:12] = offset[20:1] 共20位
// imm[31]_imm[30:21]_imm[20]_imm[19:12] = offset[20]_offset[10:1]_offset[11]_offset[19:12]
`define OP_JAL_TYPE_J    7'b110_1111        // 无条件跳转指令：jump and link，例：JAL rd,label
`define OP_JALR_TYPE_J   7'b110_0111

`define INST_NOP    32'h00000001
`define INST_NOP_OP 7'b0000001
`define INST_MRET   32'h30200073
`define INST_RET    32'h00008067

`define INST_FENCE  7'b0001111
`define INST_ECALL  32'h73
`define INST_EBREAK 32'h00100073

// J type inst
`define INST_TYPE_B 7'b1100011
`define INST_BEQ    3'b000
`define INST_BNE    3'b001
`define INST_BLT    3'b100
`define INST_BGE    3'b101
`define INST_BLTU   3'b110
`define INST_BGEU   3'b111

// CSR inst
`define INST_CSR    7'b1110011
`define INST_CSRRW  3'b001
`define INST_CSRRS  3'b010
`define INST_CSRRC  3'b011
`define INST_CSRRWI 3'b101
`define INST_CSRRSI 3'b110
`define INST_CSRRCI 3'b111

// CSR reg addr
`define CSR_CYCLE   12'hc00
`define CSR_CYCLEH  12'hc80
`define CSR_MTVEC   12'h305
`define CSR_MCAUSE  12'h342
`define CSR_MEPC    12'h341
`define CSR_MIE     12'h304
`define CSR_MSTATUS 12'h300
`define CSR_MSCRATCH 12'h340

`define RomNum 4096  // rom depth(how many words)

`define MemNum 4096  // memory depth(how many words)
`define MemBus 31:0
`define MemAddrBus 31:0

`define InstBus 31:0
`define InstAddrBus 31:0

// common regs
`define RegAddrBus 4:0
`define RegBus 31:0
`define DoubleRegBus 63:0
`define RegWidth 32
`define RegNum 32        // reg num
`define RegNumLog2 5
